package com.sq.goodline.interceptor;


import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sq.goodline.annotation.IgnoreAccessToken;
import com.sq.goodline.dao.PartnerTokenDao;
import com.sq.goodline.dao.po.PartnerToken;
import com.sq.goodline.exception.TransException;
import com.sq.goodline.util.Constants;
import com.sq.goodline.util.ContextUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class AccessTokenInterceptor extends HandlerInterceptorAdapter {

	@Autowired
	PartnerTokenDao accessTokenDao;
	
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 判断是否有 忽略用户登录 的注释，有则不进行拦截
        IgnoreAccessToken ignoreUserToken = handlerMethod.getBeanType().getAnnotation(IgnoreAccessToken.class);
        if (ignoreUserToken == null) {
            ignoreUserToken = handlerMethod.getMethodAnnotation(IgnoreAccessToken.class);
        }
        if (ignoreUserToken != null) {
            log.debug("Ignore ACCESS_TOKEN");
            return super.preHandle(request, response, handler);
        }
        //////////////////////////////////////////////////////////////
        String traceId = request.getHeader(Constants.TRACE_ID);
        if(StringUtils.isBlank(traceId)) {
        	traceId = UUID.randomUUID().toString().replace("-","");
        }
        MDC.put("TraceId", traceId);//日志追踪
        
        String userToken = request.getHeader(Constants.ACCESS_TOKEN);
        log.info("ACCESS_TOKEN:{}", userToken);

        if (StringUtils.isBlank(userToken)) {
            // 无会话令牌 
//            return true;
            throw new TransException("99", "无访问令牌");
        } else {
        	checkToken(userToken);
        }

        return super.preHandle(request, response, handler);
    }
    
    /**
     * 校验token有效性
     * @param userToken
     * @throws TransException
     */
    private void checkToken(String userToken ) throws TransException {
    	QueryWrapper<PartnerToken> qw = new QueryWrapper<>();
		qw.eq("token", userToken); 
		List<PartnerToken> accessTokenList = accessTokenDao.selectList(qw);
		if(accessTokenList==null||accessTokenList.size()==0) {
			throw new TransException("99", "令牌无效");
		}
		
		PartnerToken accessToken = accessTokenList.get(0);
		long endTime = accessToken.getEndTime().getTime();
		if(System.currentTimeMillis()>=endTime) {
			throw new TransException("11", "令牌已失效，请重新获取");
		}else {
			ContextUtil.removeThreadContext(Constants.CURRENT_TOKEN);
			ContextUtil.putThreadContext(Constants.CURRENT_TOKEN, accessToken);
		}
    }
}
